package com.moon.common.dao;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.moon.common.utils.Page;
@SuppressWarnings("unchecked")
public class BaseDaoImpl implements IBaseDao {
	
	private HibernateTemplate hibernateTemplate;
	private JdbcTemplate jdbcTemplate;
	
	@Override
	public void save(Object obj) {
		this.hibernateTemplate.save(obj);
	}

	@Override
	public void update(Object obj) {
		this.hibernateTemplate.update(obj);
	}

	@Override
	public void delete(Object obj) {
		this.hibernateTemplate.delete(obj);
	}

	@Override
	public void deleteById(Class clazz, Long id) {
		this.hibernateTemplate.delete(this.findObjectById(clazz, id));
	}

	@Override
	public void saveOrUpdate(Object obj) {
		this.hibernateTemplate.saveOrUpdate(obj);
	}

	@Override
	public void executeSql(String sql) {
		this.jdbcTemplate.execute(sql);
	}
	
	@Override
	public void executeHql(String hql) {
		Session session = this.hibernateTemplate.getSessionFactory().openSession();
		Query query = session.createQuery(hql);
		query.executeUpdate();
	}
	
	@Override
	public Object findObjectById(Class clazz, Long id) {
		return this.hibernateTemplate.get(clazz,id);
	}

	@Override
	public Object findObjectByHql(final String hql,final Map<String, Object> params) {
		return (Object) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)throws HibernateException, SQLException {
						if (hql != null) {
							Query query = session.createQuery(hql);
							Iterator it = params.keySet().iterator();
							while (it.hasNext()) {
								String key = (String) it.next();
								String value = params.get(key).toString();
								query.setParameter(key, value);
							}
							List list=query.list();
							if(list!=null&&list.size()>0)
								return list.get(0);
						}
						return null;
					}
				});
	}

	@Override
	public int getCountByHql(final String countHql) {
		return (Integer) getHibernateTemplate().execute(new HibernateCallback() {
		    public Object doInHibernate(Session session){
			    int count=0;
				Query query=session.createQuery(countHql);
				count = ((Integer) query.iterate().next()).intValue();
				return count;
			}
		});
	}

	@Override
	public List findListByHql(final String hql,final Map<String, Object> params) {
		return (List) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)throws HibernateException, SQLException {
						if (hql != null) {
							Query query = session.createQuery(hql);
							Iterator it = params.keySet().iterator();
							while (it.hasNext()) {
								String key = (String) it.next();
								Object value = params.get(key);
								query.setParameter(key, value);
							}
							List list=query.list();
							if(list!=null&&list.size()>0)
								return list;
						}
						return null;
					}
				});
	}

	@Override
	public Page findPageByHql(final int start,final int limit,final String hql,final Map<String, Object> params) {
		return (Page)this.getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {				
				Page page = null;
				if (hql != null) {
					int firstResultIndex = start;
					String countHql = "select count(*) "+hql;
					Query countQuery = session.createQuery(countHql);
					Query query = session.createQuery(hql);
					Iterator it=params.keySet().iterator();
					while(it.hasNext()){
						String key=(String)it.next();
						Object value=params.get(key);
						countQuery.setParameter(key, value);
						query.setParameter(key, value);
					}
					int totalCount = ((Long) countQuery.iterate().next()).intValue();
					if (totalCount == 0 || firstResultIndex > totalCount) {
						page = new Page();
						page.setLimit(limit);
						page.setTotalCount(totalCount);
						page.setResult(new ArrayList());
					} else {
						query.setFirstResult(firstResultIndex);
						query.setMaxResults(((firstResultIndex+1)*limit));
						List result = query.list();
						page = new Page();
						page.setStart(start);
						page.setLimit(limit);
						page.setTotalCount(totalCount);
						page.setResult(result);
					}
				}
				return page;
			}
			
		});
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

}
